package com.seed.core.util;

import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryTable;
import com.seed.util.RowKit;

import java.util.List;
import java.util.stream.Stream;

public class ConditionUtil {

    public static QueryCondition condition(QueryTable table, String column, String op, String value) {
        return condition(new QueryColumn(table, column), op, value);
    }

    public static QueryCondition condition(QueryColumn queryColumn, String op, Object value) {
        if("isNull".equalsIgnoreCase(op)) return queryColumn.isNull();
        if("isNotNull".equalsIgnoreCase(op)) return queryColumn.isNotNull();

        if(value == null || value.toString().equals("")) return QueryCondition.createEmpty();

        if("like".equalsIgnoreCase(op)) return queryColumn.like(value);
        if("likeLeft".equalsIgnoreCase(op)) return queryColumn.likeLeft(value);
        if("likeRight".equalsIgnoreCase(op)) return queryColumn.likeRight(value);
        if("notLike".equalsIgnoreCase(op)) return queryColumn.notLike(value);
        if("notLikeLeft".equalsIgnoreCase(op)) return queryColumn.notLikeLeft(value);
        if("notLikeRight".equalsIgnoreCase(op)) return queryColumn.notLikeRight(value);
        if("eq".equalsIgnoreCase(op)) return queryColumn.eq(value);
        if("ne".equalsIgnoreCase(op)) return queryColumn.ne(value);
        if("gt".equalsIgnoreCase(op)) return queryColumn.gt(value);
        if("ge".equalsIgnoreCase(op)) return queryColumn.ge(value);
        if("lt".equalsIgnoreCase(op)) return queryColumn.lt(value);
        if("le".equalsIgnoreCase(op)) return queryColumn.le(value);

        List<String> values = Stream.of(value.toString().split(","))
                .filter(StrUtil::isBlank)
                .map(e -> e.trim())
                .distinct()
                .toList();
        int size = values.size();
        if("in".equalsIgnoreCase(op)) {
            if(values.isEmpty()) return QueryCondition.createEmpty().and("false");
            return queryColumn.in(values);
        }
        if("notIn".equalsIgnoreCase(op)) {
            if(values.isEmpty()) return QueryCondition.createEmpty();
            return queryColumn.notIn(values);
        }
        if("between".equalsIgnoreCase(op)) {
            if(size == 1) return queryColumn.eq(values.get(0));
            return queryColumn.between(values.get(0), values.get(1));
        }
        if("notBetween".equalsIgnoreCase(op)) {
            if(size == 1) return queryColumn.ne(values.get(0));
            return queryColumn.notBetween(values.get(0), values.get(1));
        }

        return queryColumn.eq(value);
    }

    public static QueryCondition condition(QueryColumn queryColumn, String op, QueryColumn value) {
        if("isNull".equalsIgnoreCase(op)) return queryColumn.isNull();
        if("isNotNull".equalsIgnoreCase(op)) return queryColumn.isNotNull();

        if(value == null) return QueryCondition.createEmpty();

        if("like".equalsIgnoreCase(op)) return queryColumn.like(value);
        if("likeLeft".equalsIgnoreCase(op)) return queryColumn.likeLeft(value);
        if("likeRight".equalsIgnoreCase(op)) return queryColumn.likeRight(value);
        if("notLike".equalsIgnoreCase(op)) return queryColumn.notLike(value);
        if("notLikeLeft".equalsIgnoreCase(op)) return queryColumn.notLikeLeft(value);
        if("notLikeRight".equalsIgnoreCase(op)) return queryColumn.notLikeRight(value);
        if("eq".equalsIgnoreCase(op)) return queryColumn.eq(value);
        if("ne".equalsIgnoreCase(op)) return queryColumn.ne(value);
        if("gt".equalsIgnoreCase(op)) return queryColumn.gt(value);
        if("ge".equalsIgnoreCase(op)) return queryColumn.ge(value);
        if("lt".equalsIgnoreCase(op)) return queryColumn.lt(value);
        if("le".equalsIgnoreCase(op)) return queryColumn.le(value);

        if("in".equalsIgnoreCase(op)) throw new RuntimeException("不支持【in】列");
        if("notIn".equalsIgnoreCase(op)) throw new RuntimeException("不支持【notIn】列");
        if("between".equalsIgnoreCase(op))throw new RuntimeException("不支持【between】列");
        if("notBetween".equalsIgnoreCase(op)) throw new RuntimeException("不支持【notBetween】列");

        return queryColumn.eq(value);
    }

    /**
     * 获取关联条件
     * @param self 主表数据
     * @param selfColumn 主表对应的列
     * @param targetColumn 子表对应的列
     * @param targetTable 子表对象
     * @return 关联条件
     */
    public static QueryCondition condition(Object self, String selfColumn, String targetColumn, QueryTable targetTable) {
        QueryColumn targetQueryColumn = new QueryColumn(targetTable, targetColumn);
        if(self instanceof List<?> selfList) {
            return targetQueryColumn.in(selfList.stream().map(e -> RowKit.getSelfValue(e, selfColumn)).toList());
        }

        return targetQueryColumn.eq(RowKit.getSelfValue(self, selfColumn));
    }
}
